package com.ssm.collection.core.common.service.impl;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Condition;

import com.ssm.collection.core.common.service.BaseService;

public abstract class BaseServiceImpl<E, PK> implements BaseService<E, PK> {

	protected final Logger logger = LoggerFactory.getLogger(getClass());

	private Class<E> entityClass;

	@SuppressWarnings("unchecked")
	public Class<E> getEntityClass() {
		if (entityClass == null) {
			ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
			entityClass = (Class<E>) type.getActualTypeArguments()[0];
		}
		return entityClass;
	}

	@Autowired
	protected Mapper<E> mapper;

	public Mapper<E> getMapper() {
		return mapper;
	}

	@Transactional(readOnly = true)
	@Override
	public E getPk(PK key) {
		return mapper.selectByPrimaryKey(key);
	}
	
	@Transactional(readOnly = true)
	@Override
	public E selectOne(E entity) {
		return mapper.selectOne(entity);
	}

	@Transactional(readOnly = false)
	@Override
	public boolean insert(E entity) {
		return mapper.insertSelective(entity) > 0 ? true : false;
	}

	// @Transactional(readOnly = false)
	// @Override
	// public boolean insertSelective(E entity) {
	// return getMapper().insertSelective(entity) > 0 ? true : false;
	// }

	@Transactional(readOnly = false)
	@Override
	public boolean delete(PK key) {
		return mapper.deleteByPrimaryKey(key) > 0 ? true : false;

	}

	@Transactional(readOnly = false)
	@Override
	public boolean deleteFlag(Long id, Long operator_id) {

		E entity = null;
		try {
			Class<E> entityClass = getEntityClass();
			entity = entityClass.newInstance();

			Field[] superFields=	entityClass.getSuperclass().getDeclaredFields();
			Field[] fs = entityClass.getDeclaredFields();
			
			//设置 父类中的属性
			for (Field temp : superFields) {
				if (temp.getName().equalsIgnoreCase("delete_flag")) {
					temp.setAccessible(true); // 设置属性是可以访问的
					temp.set(entity, 1);
				}
				if (temp.getName().equalsIgnoreCase("operator_id")) {
					temp.setAccessible(true); 
					temp.set(entity, operator_id);
				}
			}
			//设置 子类中的属性
			for (Field temp : fs) {
				if (temp.getName().equalsIgnoreCase("id")) {
					temp.setAccessible(true); 
					temp.set(entity, id);
				}
			}

		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return update(entity);

	}

	// @Transactional(readOnly = true)
	// public List<E> selectByExample(Object example) {
	// return mapper.selectByExample(example);
	// }

	@Transactional(readOnly = true)
	@Override
	public List<E> selectAll(String orderBy) {
		Condition c = new Condition(getEntityClass());
		c.setOrderByClause(orderBy);
		// TODO "id asc"
		return getMapper().selectByExample(c);
	}

	@Transactional(readOnly = true)
	@Override
	public List<E> selectAll() {
		return getMapper().selectAll();
	}

	@Transactional(readOnly = true)
	@Override
	public E queryForObject(E entity) {
		List<E> list = getMapper().select(entity);
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

	@Transactional(readOnly = true)
	@Override
	public E queryForObjectByCondition(Condition condition) {
		List<E> list = getMapper().selectByExample(condition);
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

	@Transactional(readOnly = true)
	@Override
	public List<E> queryForListByCondition(Condition condition) {
		return getMapper().selectByExample(condition);
	}

	@Transactional(readOnly = false)
	@Override
	public boolean update(E entity) {
		return getMapper().updateByPrimaryKeySelective(entity) > 0 ? true : false;
	}

	// @Transactional(readOnly = false)
	// @Override
	// public boolean updateNotNull(E entity) {
	// return getMapper().updateByPrimaryKeySelective(entity) > 0 ? true : false;
	// }

	@Transactional(readOnly = true)
	@Override
	public E queryByProperty(String property, Object value) {
		Condition c = new Condition(getEntityClass());
		c.createCriteria().andEqualTo(property, value);
		List<E> list = getMapper().selectByExample(c);
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

	@Transactional(readOnly = true)
	@Override
	public List<E> queryForList(E entity) {
		return getMapper().select(entity);
	}

}
